package com.gateway.jug.gps;

import java.util.List;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.ZoomControls;

import com.gateway.jug.R;
import com.gateway.jug.interfaces.FuzzInfo;
import com.gateway.jug.interfaces.IFuzzInfoCallback;
import com.gateway.jug.interfaces.IRemoteRegistration;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;

public class FuzzMinder extends MapActivity 
{    
    private static final String TAG = "FuzzMinder";
	
    private MapView mapView;
    private MapController mc;

    private LinearLayout mLinearLayout;
    private ZoomControls mZoom;
    
    private int defaultZoomLevel = 12;
    
    List<Overlay> mapOverlays;
    MyLocationOverlay myLocationOverlay;
    
    IRemoteRegistration mService;
    
    ConnectionManager mRemoteConnection;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.map); 
        Log.d(TAG, "Set content: mapview");

        Log.d(TAG, "Registered location listener");
        
        mapView = (MapView) findViewById(R.id.mapview1);
        mc = mapView.getController();
        mc.setZoom(defaultZoomLevel);
        
        Log.d(TAG, "Obtained Map Controller");

        mLinearLayout = (LinearLayout) findViewById(R.id.zoomview);
        mZoom = (ZoomControls) mapView.getZoomControls();
        
        mLinearLayout.addView(mZoom);
        Log.d(TAG, "Added zoom controls");
        
        myLocationOverlay = new MyLocationOverlay(this, mapView);
        mapOverlays = mapView.getOverlays();
        mapOverlays.add(myLocationOverlay);
        myLocationOverlay.enableMyLocation();
        Log.d(TAG, "Added overlay for 'you are here' icon.");

        bindService(new Intent("com.gateway.jug.interfaces.IRemoteRegistration"), getConnectionManager(), Context.BIND_AUTO_CREATE);
        Log.d(TAG, "Bound to remote service.");
    }

    @Override
	protected void onPause() {
		super.onPause();
		if (myLocationOverlay != null) {
			myLocationOverlay.disableMyLocation();			
		}
    	unbindService(getConnectionManager());        	
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (myLocationOverlay != null) {
			myLocationOverlay.enableMyLocation();
		}
        bindService(new Intent("com.gateway.jug.interfaces.IRemoteRegistration"), getConnectionManager(), Context.BIND_AUTO_CREATE);
	}

	@Override
    protected boolean isRouteDisplayed() {
        return false;
    }        

	private ConnectionManager getConnectionManager() {
		if (mRemoteConnection == null) {
			mRemoteConnection = new ConnectionManager();			
		}
		return mRemoteConnection;
	}
	
    private class ConnectionManager implements ServiceConnection {
        public void onServiceConnected(ComponentName className, IBinder service) {
            mService = IRemoteRegistration.Stub.asInterface(service);

            try {
                mService.registerCallback(mCallback);
            } catch (RemoteException e) { // no need to perform any handling
            	Log.e(TAG, "Error occured, should be benign", e);
            }

            // As part of the sample, tell the user what happened.
            Toast.makeText(FuzzMinder.this, R.string.fuzz_service_client_connected,
                    Toast.LENGTH_SHORT).show();
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mService = null;

            // As part of the sample, tell the user what happened.
            Toast.makeText(FuzzMinder.this, R.string.fuzz_service_client_disconnected,
                    Toast.LENGTH_SHORT).show();
        }
    };    

    private IFuzzInfoCallback mCallback = new IFuzzInfoCallback.Stub() {

		@Override
		public void updateInfo(FuzzInfo info) throws RemoteException {
            mHandler.sendMessage(mHandler.obtainMessage(MAP_MSG, info));			
		}
    	
    };

    private static final int MAP_MSG = 1;

    private Handler mHandler = new Handler() {
        @Override public void handleMessage(Message msg) {
            switch (msg.what) {
                case MAP_MSG:
                	if (msg.obj != null) {
                		FuzzInfo fi = (FuzzInfo) msg.obj;
                        GeoPoint p = new GeoPoint((int) (fi.currentlat * 1E6), 
                                                  (int) (fi.currentlong * 1E6));
                        mc.animateTo(p);
                        mapView.invalidate();                		
                	}
                    break;
                default:
                    super.handleMessage(msg);
            }
        }

    };
	
}
